package main;

import help.HelpWindow;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import javax.swing.JPanel;
import javax.swing.JApplet;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import settings.SettingsWindow;
import main.TextArea;

/**
 * 
 * @author Daniel Collins
 * @author Balazs Pete
 * @author David Doyle
 *
 */
public class MainWindow extends JApplet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -6976007482485480969L;
	private static JPanel jContentPane = null;
	private static TextArea jTextArea = null;
	private static JTextArea jLawArea = null;
	private static JScrollPane jScrollPane = null;
	private JScrollPane lawPane = null;
	public static LineNumber numbersPane = null;
	private JLabel jLabel = null;
	protected static JPanel toolbar = null;
	private static int x1 = 0;
	private int x2 = 0, x3 = 0, x4 = 0;
	private int mainBodyTopPosition = 100;
	private static boolean enableSymbolSpaces = false;
	private static boolean enableLawToolbar = true;
	private static boolean enableMagicRob = true;
	private static JFrame settingsWindow = null;
	private static JFrame helpWindow = null;
	private JButton settingsButton = null;
	private JButton helpButton = null;
	
	//getting display attributes
	public int maxHeight =GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height;
	public int maxWidth = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
	
	private Point windowSize = setWindowSize();
	
	/**
	 * This is the xxx default constructor
	 * 
	 */
	public MainWindow() {
		super();
		configSettingsWindow();
		configHelpWindow();
		
	}
	
	public void init() {
		this.setSize(windowSize.x,windowSize.y);
		this.setContentPane(getJContentPane());
		
		this.getContentPane().addHierarchyBoundsListener(new HierarchyBoundsListener(){
			@Override
			public void ancestorMoved(HierarchyEvent arg0) {
			}
			@Override
			public void ancestorResized(HierarchyEvent arg0) {
				redrawWindow();				
			}			
		});
	}

	/**
	 * This method initializes jContentPane
	 * @return javax.swing.JPanel
	 * @author Daniel Collins
	 * @author Balazs Pete
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			setTopPosition();
			jLabel = new JLabel();
			jLabel.setBounds(new Rectangle(getBounds().width-300,5, 80, 16));
			jLabel.setText("Milestone 3");
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(getJScrollPane(), null);
			jContentPane.add(getLawPane(), null);
			jContentPane.add(jLabel, null);
			jContentPane.add(getNumbersPane(),null);
			toolbar = new symbols.Toolbar();
			setToolbarBounds();
			jContentPane.add(toolbar);
			jContentPane.add(getHelpButton());
			jContentPane.add(getSettingsButton());
		}
		return jContentPane;
	}

	/**
	 * 
	 * @return
	 */
	private JButton getSettingsButton(){
		if(settingsButton==null){
			settingsButton = new JButton("Settings");
			settingsButton.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					settingsVisible(true);
				}
			});
			settingsButton.setBounds(new Rectangle(getBounds().width-115,5, 100, 20));
		}
		return settingsButton;
	}
	
	/**
	 * 
	 * @return
	 */
	private JButton getHelpButton(){
		if(helpButton==null){
			helpButton = new JButton("Help");
			helpButton.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					helpVisible(true);
				}
			});
			helpButton.setBounds(new Rectangle(getBounds().width-230,5, 100, 20));
		}
		return helpButton;
	}
	
	/**
	 * This method initializes jTextArea
	 * @return javax.swing.JTextArea
	 * @author Daniel Collins, Balazs Pete
	 */
	private TextArea getJTextArea() {
		if (jTextArea == null) {
			jTextArea = new TextArea(maxWidth, maxHeight);
		}
		return jTextArea;
	}
	
	/**
	 * Method to get the law area
	 * @return law area
	 * @author David Doyle
	 */
	private JTextArea getJLawArea() {
		if (jLawArea == null) {
			jLawArea = new LawBar(maxWidth, maxHeight);
			jLawArea.setEditable(false);
		}
		return jLawArea;
	}

	/**
	 * This method initializes jScrollPane
	 * @return javax.swing.JScrollPane
	 * @author Daniel Collins
	 */
	private JScrollPane getJScrollPane() {
		Rectangle bounds = getBounds();
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			setTopPosition();
			setWindowBounds();
			
			jScrollPane.setBounds(36,mainBodyTopPosition,x2-33,bounds.height-mainBodyTopPosition);
			jScrollPane.setViewportView(getJTextArea());
		}
		return jScrollPane;
	}

	/**
	 * Method initializing the law toolbar/pane/area
	 * @return lawPane
	 * @author David Doyle
	 */
	private JScrollPane getLawPane() {
		Rectangle bounds = getBounds();
		if (lawPane == null) {
			lawPane = new JScrollPane();
			setTopPosition();
			
			setWindowBounds();
			
			//text area adapts to the size of the window
			lawPane.setBounds(x4,mainBodyTopPosition,x3,bounds.height-mainBodyTopPosition);
			lawPane.setViewportView(getJLawArea());
		}
		return lawPane;
	}
	
	private LineNumber getNumbersPane() {
		Rectangle bounds = getBounds();
		if (numbersPane == null) {
			setTopPosition();
			setWindowBounds();
			numbersPane = new LineNumber(10,jTextArea.getHeight());
			numbersPane.setBounds(new Rectangle(3,mainBodyTopPosition,30,bounds.height-mainBodyTopPosition));
		}
		return numbersPane;
	}
		
	/**
	 * Method to set the size of the window
	 * (possibility to get a size from config file later / remember previous window size)
	 * @return window size
	 * @author Balazs Pete
	 */
	private Point setWindowSize(){
		return new Point(maxWidth/2,maxHeight-100);
	}
	
	/**
	 * Method to access the insertText method of the text area
	 * @param text text to be inserted
	 */
	public static void insertText(String text){
		((TextArea) jTextArea).insertText(text,enableSymbolSpaces);
	}
	
	/**
	 * Method to return the focus to the etext area
	 * @author Balazs Pete
	 */
	public static void textAreaFocus(){
		jTextArea.grabFocus();
	}
	
	/**
	 * Changes the value of the enableSymbolSpaces variable, depending on input
	 * @param status status to be set
	 */
	public static void setEnableSymbolSpacesStatus(boolean status){
		enableSymbolSpaces = status;
	}
	
	/**
	 * Gets the value of the enableSymbolSpaces variable
	 * @return status of variable
	 */
	public static boolean getSymbolSpacesStatus(){
		return enableSymbolSpaces;
	}
	
	/**
	 * Method to change the value of enableLawToolbar variable
	 * @param status future status
	 * @author Balazs Pete
	 */
	public static void setEnableLawToolbarStatus(boolean status){
		enableLawToolbar = status;
	}
	
	/**
	 * Method to check if the law tool bar is hidden or not
	 * @return status of law bar
	 * @author Balazs Pete
	 */
	public static boolean getLawToolbarStatus(){
		return enableLawToolbar;
	}
	
	/**
	 * Sets the x position of the main body elements
	 * @author Balazs Pete
	 */
	protected void setTopPosition(){
		if(950<=getBounds().width){
			mainBodyTopPosition = 65;
		} else if (495<=getBounds().width){
			mainBodyTopPosition = 100;
		} else if (352<=getBounds().width){
			mainBodyTopPosition = 135;
		} else{
			mainBodyTopPosition = 160;
		}
	}
	
	/**
	 * Changes the visibility of the settings window
	 * @param v true to show settings window
	 * @author Balazs Pete
	 */
	public static void settingsVisible(boolean v){
		settingsWindow.setVisible(v);
	}
	
	/**
	 * Changes the visibility of the help window
	 * @param v true to show help window
	 * @author Balazs Pete
	 */
	public static void helpVisible(boolean v){
		helpWindow.setVisible(v);
	}
	
	/**
	 * Method to configure the settings window
	 * @author Balazs Pete
	 */
	private void configSettingsWindow(){
		settingsWindow = new SettingsWindow();
		settingsWindow.setSize(300, 300);
		settingsWindow.addComponentListener(new ComponentListener(){
			@Override
			public void componentResized(ComponentEvent e) {
			}

			@Override
			public void componentMoved(ComponentEvent e) {
			}

			@Override
			public void componentShown(ComponentEvent e) {
			}

			@Override
			public void componentHidden(ComponentEvent e) {
				redrawWindow();
			}
		});
	}
	
	private void configHelpWindow(){
		helpWindow = new HelpWindow();
		helpWindow.setSize(400, 500);
		helpWindow.addComponentListener(new ComponentListener(){
			@Override
			public void componentResized(ComponentEvent e) {
			}

			@Override
			public void componentMoved(ComponentEvent e) {
			}

			@Override
			public void componentShown(ComponentEvent e) {
			}

			@Override
			public void componentHidden(ComponentEvent e) {
				redrawWindow();
			}
		});
	}
	
	/**
	 * Method to set variables controlling the bounds of the window elements
	 * @author David Doyle
	 * @author Balazs Pete
	 */
	private void setWindowBounds(){
		Rectangle bounds = getBounds();
		setTopPosition();
		if(enableLawToolbar){
			x1 = bounds.width-9;
			x2 = (x1/10)*8;
			x3 = (x1/10)*2;
			x4 = 6 + x2;
		} else {
			x1 = bounds.width-6;
			x2 = x1;
			x3 = 0;
			x4 = x2;
		}
	}
	
	/**
	 * Text area adapt to the size of the window
	 * @author Balazs Pete
	 * @author David Doyle
	 */
	public void redrawWindow(){
		Rectangle bounds = getBounds();
		setWindowBounds();
		setToolbarBounds();
		jScrollPane.setBounds(36,mainBodyTopPosition,x2-33,bounds.height-mainBodyTopPosition);	
		jScrollPane.setViewportView(getJTextArea());
		lawPane.setBounds(x4,mainBodyTopPosition,x3,bounds.height-mainBodyTopPosition);
		lawPane.setViewportView(getJLawArea());
		jLabel.setBounds(new Rectangle(getBounds().width-300,5, 80, 16));
		numbersPane.setBounds(3,mainBodyTopPosition,30,bounds.height-mainBodyTopPosition);
		settingsButton.setBounds(new Rectangle(getBounds().width-115,5, 100, 20));
		helpButton.setBounds(new Rectangle(getBounds().width-230,5, 100, 20));
		
	}
	
	/**
	 * Method to get the vertical scroll bar of the main scroll pane
	 * @return vertical scroll bar
	 * @author Balazs Pete
	 */
	public static JScrollBar getJScrollPaneVerticalScrollBar(){
		return jScrollPane.getVerticalScrollBar();
	}
	
	/**
	 * Method to call the updateText method on the text area
	 * @author Balazs Pete
	 */
	public static void updateText(){
		((TextArea) jTextArea).updateTextVariable();
	}
	
	/**
	 * 
	 */
	public static void setToolbarBounds(){
		if(950<x1){
			toolbar.setBounds(4,30,950,150);
		} else {
			toolbar.setBounds(4,30,x1,150);
		}
	}
	
	/**
	 * Method to change status of enableMagicRob
	 * @param status status of Magic Rob
	 */
	public static void setMagicRoc(boolean status){
		enableMagicRob = status;
	}
	
	/**
	 * Mehtod to get status of enableMagicRob
	 * @return status of magic rob
	 */
	public static boolean getMagicRob(){
		return enableMagicRob;
	}
}